﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

//https://go.microsoft.com/fwlink/?LinkId=234236 上介绍了“用户控件”项模板

namespace Acoris.UWP.Demo
{
    using static System.Diagnostics.Debug;
    using System.Numerics;

    using Microsoft.Graphics.Canvas;
    using Microsoft.Graphics.Canvas.Brushes;
    using Microsoft.Graphics.Canvas.Geometry;
    using Microsoft.Graphics.Canvas.Effects;
    using Microsoft.Graphics.Canvas.Text;
    using Microsoft.Graphics.Canvas.UI.Xaml;

    using System.Text.RegularExpressions;

    using Windows.UI;

    [Demo(typeof(StackDiagram), Name = "层叠图")]
    public sealed partial class StackDiagram : UserControl
    {
        private const string RegexPattern = @"(?'content'[\w]+)(\r|\n)";
        private const string TestContent = @"";

        private const float Width = 256f;
        private const float Height = 54.85f;
        private static readonly float rate = (float)Math.Tan(48);

        private Vector2[] points = new Vector2[] {
            new Vector2(Height / rate ,0),
            new Vector2(0,Height),
            new Vector2(Width,Height),
            new Vector2(Width - Height / rate,0)
        };
        private CanvasGeometry geometry;

        private float drawing_y = 100f;
        private float drawing_x = 100f;

        private readonly List<string> line = new List<string>();

        public StackDiagram()
        {
            this.InitializeComponent();
        }

        private void canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args)
        {
            var session = args.DrawingSession;
            (Color.FromArgb(255, 0, 122, 204)).ToHSL(out var h, out var s, out var l);

            var index = 0.3f;
            var y = drawing_y + line.Count * 48f;

            for (int i = line.Count - 1; i >= 0; i--)
            {
                var drawing = line[i];
                session.FillGeometry(geometry, drawing_x, y, Colors.Black.FromHSL(h, s, index));
                index += .1f;
                session.DrawText(drawing, new Vector2(drawing_x + 16 + Height / rate, y + 16), Colors.White);
                y -= 48f;
            }
        }

        private void input_TextChanged(object sender, TextChangedEventArgs e)
        {
            line.Clear();
            line.AddRange(input.Text.Split('\r'));
            canvas.Invalidate();
        }

        private void canvas_CreateResources(CanvasControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
        {

            geometry = CanvasGeometry.CreatePolygon(canvas, points);
        }
    }

    public static class ColorExtensions
    {
        public static Color FromHSL(this Color thisColor, float h, float s, float l)
        {
            var color = new float[3];
            var q = 0f;
            var p = 0f;
            var h_k = 0f;


            if (l < .5f)
            {
                q = l * (1 + s);
            }
            else
            {
                q = l + s - (l * s);
            }

            p = 2 * l - q;

            h_k = h / 360f;

            var t = new[] { h_k + .33333334f, h_k, h_k - .33333334f };
            for (int i = 0; i < 3; i++)
            {
                if (t[i] > 1f)
                {
                    t[i] -= 1f;
                }
                else if (t[i] < 0f)
                {
                    t[i] += 1f;
                }
            }

            for (int i = 0; i < 3; i++)
            {
                if (t[i] < .16666667f)
                {
                    color[i] = p + ((q - p) * 6 * t[i]);
                }
                else if (t[i] >= .16666667f && t[i] < .5f)
                {
                    color[i] = q;
                }
                else if (t[i] >= .5f && t[i] < .66666667f)
                {
                    color[i] = p + ((q - p) * 6 * (2 / 3f - t[i]));
                }
                else
                {
                    color[i] = p;
                }
            }


            var c = new Color
            {
                R = (byte)(color[0] * 255f),
                G = (byte)(color[1] * 255f),
                B = (byte)(color[2] * 255f),
                A = 255
            };

            WriteLine(c);

            return c;
        }

        public static void ToHSL(this Color color, out float h, out float s, out float l)
        {
            var r = color.R / 255f;
            var g = color.G / 255f;
            var b = color.B / 255f;

            var max = Math.Max(r, Math.Max(g, b));
            var min = Math.Min(r, Math.Min(g, b));

            l = 0.5f * (max + min);

            if (max == min)
            {
                h = 0;
            }
            else
            {
                h = 60;

                if (max == r && color.G >= color.B)
                {
                    h *= (g - b) / (max - min);
                }
                else if (max == r && color.G < color.B)
                {
                    h = h * (g - b) / (max - min) + 360f;
                }
                else if (max == g)
                {
                    h = h * (b - r) / (max - min) + 120f;
                }
                else if (max == b)
                {
                    h = h * (r - g) / (max - min) + 240f;
                }
            }

            if (max == min || l == 0)
            {
                s = 0;
            }
            else
            {
                s = 1 - min / max;
            }

            WriteLine($"h:{h},s:{s},l:{l}");
        }
    }
}

